﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Text;

namespace YeaTrip.Framework.Validation
{

    #region 非负整数验证

    /// <summary>
    /// 提供非负整数的验证类
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class NotNegativeIntegerAttribute : ValidationAttribute
    {

        public NotNegativeIntegerAttribute()
        {
            ErrorMessage = "必须为非负整数";
        }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }
            try
            {
                if (Math.Truncate(Convert.ToDouble(value)) != Convert.ToDouble(value))
                {
                    return false;
                }
                if (Convert.ToDouble(value) < 0)
                {
                    return false;
                }

            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }
    }

    /// <summary>
    /// 提供非负整数的验证程序
    /// </summary>
    public class NotNegativeIntegerValidator : DataAnnotationsModelValidator
    {
        string message;

        public NotNegativeIntegerValidator(ModelMetadata metadata, ControllerContext context, NotNegativeIntegerAttribute attribute)
            : base(metadata, context, attribute)
        {
            message = attribute.ErrorMessage;

        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = message,
                ValidationType = "notNegativeInteger"
            };
            return new[] { rule };
        }
    }

    #endregion

    #region 无效匹配验证

    /// <summary>
    /// 提供无效匹配的验证类。当被验证的值等于设定的某一个值时，验证失败
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class FalseMatchAttribute : ValidationAttribute
    {
        public string[] FalseMatchList { get; set; }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }
            foreach (var item in FalseMatchList)
            {
                if (value.ToString().Trim()==item.Trim())
                {
                    return false;
                }
            }
            return true;
        }
    }

    /// <summary>
    /// 提供无效匹配的验证程序
    /// </summary>
    public class FalseMatchValidator : DataAnnotationsModelValidator
    {
        string message;
        string [] falseMatchList;

        public FalseMatchValidator(ModelMetadata metadata, ControllerContext context, FalseMatchAttribute attribute)
            : base(metadata, context, attribute)
        {
            message = attribute.ErrorMessage;
            falseMatchList = attribute.FalseMatchList;

        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = message,
                ValidationType = "falseMatch"
            };
            rule.ValidationParameters.Add("falseMatchList", falseMatchList);
            return new[] { rule };
        }
    }

    #endregion

    #region 正整数验证

    /// <summary>
    /// 提供正整数的验证类
    /// </summary>
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
    public class PositiveIntegerAttribute : ValidationAttribute, IClientValidatable
    {

        public PositiveIntegerAttribute()
        {
            ErrorMessage = "必须为正整数";
        }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }
            try
            {
                if (Math.Truncate(Convert.ToDouble(value)) != Convert.ToDouble(value))
                {
                    return false;
                }
                if (Convert.ToDouble(value) <= 0)
                {
                    return false;
                }

            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
                ValidationType = "positiveinteger"
            };
            return new[] { rule };
        }
    }

    #endregion

    #region 输入长度验证

    /// <summary>
    /// 提供输入长度的验证类
    /// </summary>
    [AttributeUsage(AttributeTargets.Property|AttributeTargets.Field, AllowMultiple = true)]
    public class InputLengthAttribute : ValidationAttribute,IClientValidatable
    {
        public int maxLength { get; set; }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }
            byte[] length = Encoding.UTF8.GetBytes(Convert.ToString(value));
            if (length.Length > maxLength)
                return false;
            return true;
        }
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage =  FormatErrorMessage(metadata.GetDisplayName()),
                ValidationType = "inputlength"
            };
            rule.ValidationParameters.Add("maxlength", maxLength);
            return new[] { rule };
        }
    }

    #endregion

    #region 日期验证
    /// <summary>
    /// 日期验证（不包括时间）类
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class DateAttribute : RegularExpressionAttribute
    {
        public DateAttribute()
            : base(RegExpress.DateExpress) { }
    }

    /// <summary>
    /// 日期验证（包括时间）类
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class DateTimeAttribute : RegularExpressionAttribute
    {
        public DateTimeAttribute()
            : base(RegExpress.DateTimeExpress) { }
    }
    #endregion

    #region CheckBoxChecked验证

    /// <summary>
    /// 提供CheckBoxChecked的验证类
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class CheckBoxCheckedAttribute : ValidationAttribute
    {

        public override bool IsValid(object value)
        {
            return true;
            return Convert.ToBoolean( value );

        }
    }

    /// <summary>
    /// 提供CheckBoxChecked的验证程序
    /// </summary>
    public class CheckBoxCheckedValidator : DataAnnotationsModelValidator
    {
        string message;

        public CheckBoxCheckedValidator(ModelMetadata metadata, ControllerContext context, CheckBoxCheckedAttribute attribute)
            : base(metadata, context, attribute)
        {
            message = attribute.ErrorMessage;

        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = message,
                ValidationType = "checkBoxChecked"
            };
            return new[] { rule };
        }
    }

    #endregion

    #region 验证用正则
    /// <summary>
    /// 验证用正则类
    /// </summary>
    public class RegExpress
    {
        public const string DateExpress = "^(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)$";

        ////日期验证（不包括时间）
        //public const string DateExpress = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))$";

        //日期验证（包括时间）
        public const string DateTimeExpress = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[1-9])|(1[0-2]))\\:([0-5][0-9])((\\s)|(\\:([0-5][0-9])\\s))([AM|PM|am|pm]{2,2})))?$";

        //手机邮箱验证
        public const string PhoneEmailExpress = "(^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\\d{8})$)|(^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$)";

        //手机验证
        public const string PhoneExpress = "^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\\d{8})$";

        //邮箱验证
        public const string EmailExpress = "^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$";
 

        //固定电话验证（区号+主号+分机）
        public const string TelExpress = "^((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?$";

        //邮政编码
        public const string PostCodeExpress = "^\\d{6}$";

        //确认号
        public const string ConfirmNoExpress = "^\\d{16}$";

        //申请单号
        public const string ApplyNo = "^\\d{0,16}$";

        //姓名验证
        public const string NameExpress = "^[\\u4e00-\\u9fa5\\/0-9A-Za-z\\s]*$";

        //登陆账号
        public const string AgentIdExpress = "^[0-9A-Za-z]*$";

        //商户号
        public const string SupplierIdExpress = "^[0-9]{0,32}$";
        
        //英文姓名验证
        public const string EnglishtNameExpress = "^[A-Za-z]*$";

    }
    #endregion


}
